package org.example.contestb.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;

import org.example.contestb.Mapper.DoctorMapper;
import org.example.contestb.Mapper.MessageMapper;
import org.example.contestb.entity.BO.LoginBO;
import org.example.contestb.entity.DTO.LoginDTO;
import org.example.contestb.entity.DTO.MessageDTO;
import org.example.contestb.entity.DTO.RegisterDTO;
import org.example.contestb.entity.Doctor;
import org.example.contestb.entity.Message;
import org.example.contestb.service.DoctorService;
import org.example.contestb.util.EmailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class DoctorServiceImpl implements DoctorService {

    @Autowired
    DoctorMapper doctorMapper;
    @Autowired
    MessageMapper messageMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 注册
     * @param registerDTO
     */
    @Override
    public Doctor Register(RegisterDTO registerDTO) {
        LambdaQueryWrapper<Doctor> lambda = Wrappers.lambdaQuery();
        lambda.eq(Doctor::getUsername,registerDTO.getUsername());
        Doctor doctors = doctorMapper.selectOne(lambda);

        //用户名验证
        if(doctors != null){
            throw new RuntimeException("用户名已存在！");
        }
        //验证码验证
        String code = (String) redisTemplate.opsForValue().get("EMAIL_CODE_" + registerDTO.getEmail());
        if(code.isEmpty() || !code.equals(registerDTO.getCode())){
            throw new RuntimeException("验证码无效或已过期");
        }
        //就职时间
        Date defaultTime;
        try {
            defaultTime = new SimpleDateFormat("yyyy-MM-dd").parse("2025-01-01");
        } catch (ParseException e) {
            throw new RuntimeException("日期解析错误");
        }

        Doctor doctor = Doctor.builder()
                .username(registerDTO.getUsername())
                .password(SecureUtil.sha256(registerDTO.getPassword()))
                .email(registerDTO.getEmail())
                .uuid(UUID.randomUUID().toString())
                .phone("18665471546")
                .age(27)
                .gender("男")
                .department("心内科")
                .employmentAddress("吉大一院")
                .employmentTime(defaultTime)
                .workAddress("心内科162室")
                .role(1)
                .status(1)
                .introduction("No.1188,Wuzhong Avenue,Wuzhong District,Suzhou,Jiangsu Province")
                .avatar("https://i1.hdslb.com/bfs/face/4add3acfc930fcd07d06ea5e10a3a377314141c2.jpg@150w_150h.jpg")
                .build();
        doctorMapper.insert(doctor);
        return doctor;
    }

    /**
     * 登录
     * @param loginDTO
     * @return
     */
    @Override
    public LoginBO login(LoginDTO loginDTO) {
        LambdaQueryWrapper<Doctor> lambda = Wrappers.lambdaQuery();
        lambda.eq(Doctor::getUsername,loginDTO.getUsername());
        Doctor doctor = doctorMapper.selectOne(lambda);
        if(doctor == null || !doctor.getPassword().equals(SecureUtil.sha256(loginDTO.getPassword()))){
            throw new RuntimeException("用户名或密码错误");
        }
        if(doctor.getStatus() == 0){
            throw new RuntimeException("您的帐户已被封禁，请联系管理员解封！");
        }
        Integer role = doctor.getRole();
        String userId = doctor.getUuid();
        return LoginBO.builder()
                .role(role)
                .userId(userId)
                .build();
    }

    /**
     * 发送验证码
     * @param e_mail
     * @return
     */
    public String sendCode(String e_mail){
        if(e_mail == null){
            throw new RuntimeException("邮箱不能为空");
        }
        String patt = "[1-9][0-9]{4,}@qq\\.com";
        Pattern r = Pattern.compile(patt);
        Matcher matcher = r.matcher(e_mail);
        if(!matcher.find()){
            throw new RuntimeException("邮箱格式不正确");
        }
        // 生成随机验证码
        String code = String.valueOf(new Random().nextInt(899999) + 100000);
        // 将验证码存储到 Redis 中，设置 5 分钟过期时间
        redisTemplate.opsForValue().set("EMAIL_CODE_" + e_mail, code, 5, TimeUnit.MINUTES);
        // 调用工具类发送邮件
        EmailUtil.sendEmail(e_mail, code);
        return "success";
    }

    @Override
    public String updateCode(String formerPassword,String presentPassword) {
        String userId = StpUtil.getLoginIdAsString();
        if(presentPassword == null || presentPassword.length() < 6 || presentPassword.length() > 20){
            throw new RuntimeException("密码格式错误");
        }

        QueryWrapper<Doctor> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uuid",userId);
        Doctor doctor = doctorMapper.selectOne(queryWrapper);
        if(!doctor.getPassword().equals(SecureUtil.sha256(formerPassword))){
            throw new RuntimeException("原密码错误");
        }

        UpdateWrapper<Doctor> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("uuid",userId).set("password",SecureUtil.sha256(presentPassword));
        doctorMapper.update(null,updateWrapper);
        return "修改成功！";
    }

    @Override
    public Doctor display() {
        String userId = StpUtil.getLoginIdAsString();
        QueryWrapper<Doctor> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uuid",userId);
        Doctor doctor = doctorMapper.selectOne(queryWrapper);
        return doctor;
    }

    @Override
    public String contactUs(MessageDTO messageDTO) {
        if(messageDTO.getContent().trim().isEmpty() || messageDTO.getEmail().trim().isEmpty() || messageDTO.getUsername().trim().isEmpty()){
            throw new RuntimeException("请填写完整信息") ;
        }

        String userId = StpUtil.getLoginIdAsString();
        Message message = Message.builder()
                .doctorId(userId)
                .content(messageDTO.getContent())
                .username(messageDTO.getUsername())
                .email(messageDTO.getEmail())
                .status("待处理")
                .build();
        messageMapper.insert(message);
        return "您的建议已收到！";
    }
}
